﻿using Avalonia;
using KinonekoSoftware.Foundation.UI.ViewModels;

namespace KinonekoSoftware.Platform.Controls
{
    public partial class DialogHost : ContentControl
    {

        public static readonly StyledProperty<ManagedLifetimeObject> ViewModelProperty;
        public static readonly StyledProperty<string>                BusyTextProperty;
        public static readonly DirectProperty<DialogHost, bool>      IsOpenedProperty;
        public static readonly DirectProperty<DialogHost, bool>      IsBusyProperty;
        public static readonly DirectProperty<DialogHost, object>    DialogProperty;

        static DialogHost()
        {
            ViewModelProperty = AvaloniaProperty.Register<DialogHost, ManagedLifetimeObject>(nameof(ViewModel));
            BusyTextProperty  = AvaloniaProperty.Register<DialogHost, string>(nameof(BusyText));
            IsOpenedProperty  = AvaloniaProperty.RegisterDirect<DialogHost, bool>(nameof(IsOpened), x => x._isOpened);
            IsBusyProperty    = AvaloniaProperty.RegisterDirect<DialogHost, bool>(nameof(IsBusy), x => x._isBusy);
            DialogProperty    = AvaloniaProperty.RegisterDirect<DialogHost, object>(nameof(Dialog), x => x._content);

            ViewModelProperty.Changed.Subscribe(OnViewModelPropertyChanged);
        }

        private object _content;
        private bool   _isOpened;
        private bool   _isBusy;

        private static void OnViewModelPropertyChanged(AvaloniaPropertyChangedEventArgs<ManagedLifetimeObject> e)
        {
            var d        = (DialogHost)e.Sender;
            var newValue = e.GetNewValue<ManagedLifetimeObject>();

            if (newValue != null)
            {
                try
                {
                    var v = Xplat.Associate(newValue);
                    d.Dialog = v;
                }
                catch(Exception ex)
                {
                    //
                    var temp = new InternalErrorPageVM(ex, newValue.GetType());
                    var v    = Xplat.Associate(temp);

                    d.Dialog = v;
                }
            }
            else
            {
                d.Dialog = null;
            }
        }
        
        public DialogHost()
        {
            _ViewModelErrorTypeTracker = new Dictionary<Type, int>();
            _stack                     = new Stack<DialogBase>();
        }

        public ManagedLifetimeObject ViewModel
        {
            get => GetValue(ViewModelProperty);
            set => SetValue(ViewModelProperty, value);
        }
        
        public bool IsBusy
        {
            get => _isBusy;
            private set => SetAndRaise(IsBusyProperty, ref _isBusy, value);
        }

        public string BusyText
        {
            get => GetValue(BusyTextProperty);
            set => SetValue(BusyTextProperty, value);
        }

        public bool IsOpened
        {
            get => _isOpened;
            private set => SetAndRaise(IsOpenedProperty, ref _isOpened, value);
        }

        public object Dialog
        {
            get => _content;
            private set => SetAndRaise(DialogProperty, ref _content, value);
        }
    }
}
